home *** CD-ROM | disk | FTP | other *** search
- /*
- ** Apple Macintosh Developer Technical Support
- **
- ** File: AECustom.c
- ** Written by: Eric Soldan
- **
- ** Copyright © 1990-1991 Apple Computer, Inc.
- ** All rights reserved.
- */
-
-
-
- /*****************************************************************************/
-
-
-
- #include "App.h" /* Get the application includes/typedefs, etc. */
- #include "App.defs.h" /* Get various application definitions. */
- #include "App.protos.h" /* Get the prototypes for application. */
-
- #ifndef __ERRORS__
- #include <Errors.h>
- #endif
-
- #ifndef __TEXTEDITCONTROL__
- #include "TextEditControl.h"
- #endif
-
- #ifndef __UTILITIES__
- #include "Utilities.h"
- #endif
-
-
-
- /*****************************************************************************/
-
-
-
- extern Boolean gHasAppleEvents;
- /* This is defined and initialized by the DTS.Lib..framework file AERequired.c.
- ** This means that InitRequiredAppleEvents must be called prior to calling
- ** InitConnectAppleEvents (a DTS.Lib..framework function), or before calling
- ** InitCustomAppleEvents (a DTS.StyleChat function). */
-
-
- static pascal OSErr ReceiveMessage(AppleEvent *message, AppleEvent *reply, long refcon);
-
-
-
- /*****************************************************************************/
-
-
-
- static AEHandler keywordsToInstall[] = {
- { kCustomEventClass, keyAppMessage, (AEEventHandlerProcPtr)ReceiveMessage, nil }
- }; /* These are the custom AppleEvents. */
-
- #define kNumKeywords (sizeof(keywordsToInstall) / sizeof(AEHandler))
-
-
-
- /*****************************************************************************/
- /*****************************************************************************/
-
-
-
- /* Install our custom AppleEvents. This is done in addition to installing
- ** the required AppleEvents. InitAppleEvents, which installs the required
- ** AppleEvents, must be called first, since it sets up some global values. */
-
- #pragma segment AppleEvents
- void InitCustomAppleEvents(void)
- {
- OSErr err;
- short i;
-
- if (gHasAppleEvents) {
- for (i = 0; i < kNumKeywords; ++i) {
-
- if (!keywordsToInstall[i].theUPP)
- keywordsToInstall[i].theUPP = NewAEEventHandlerProc(keywordsToInstall[i].theHandler);
-
- err = AEInstallEventHandler(
- keywordsToInstall[i].theEventClass, /* What class to install. */
- keywordsToInstall[i].theEventID, /* Keywords to install. */
- keywordsToInstall[i].theUPP, /* The AppleEvent handler. */
- 0L, /* Unused refcon. */
- false /* Only for our app. */
- );
-
- if (err) {
- HCenteredAlert(rErrorAlert, nil, gAlertFilterUPP);
- return;
- }
- }
- }
- }
-
-
-
- /*****************************************************************************/
-
-
-
- /* Send some type of message to the application we are connected to. Most of the
- ** targeting information is the same for various different messages. Given this,
- ** this function builds an AppleEvent, adds the common information to the AppleEvent,
- ** and then switches for the various different message types. A similar factoring
- ** process is done at the receiving end. */
-
- #pragma segment AppleEvents
- OSErr SendMessage(FileRecHndl frHndl, short messageType)
- {
- AEAddressDesc remoteLoc;
- OSErr err;
- AppleEvent theAevt, reply;
- long windTag[2];
- short i;
- WindowPtr oldPort;
- TEHandle te;
- char hstate;
- Handle hText;
- StScrpHandle styl;
- long size;
-
- remoteLoc = (*frHndl)->connect.remoteLoc;
-
- if (!(*frHndl)->connect.connected) {
- if (remoteLoc.dataHandle) {
- AEDisposeDesc(&remoteLoc);
- (*frHndl)->connect.remoteLoc.dataHandle = nil;
- }
- return(noErr);
- }
-
- oldPort = SetFilePort(frHndl);
-
- theAevt.dataHandle = reply.dataHandle = nil;
- /* Make sure disposing of the descriptors is okay in all cases. */
- /* Even though the AppleEvent manager nils out the handle upon failure,
- ** the below code doesn't necessarily call the AppleEvent manager for each
- ** descriptor. By etting them to nil here, this allows us to just try to
- ** dispose of the descriptors at the bottom of the function. */
-
- err = AECreateAppleEvent( /* CREATE EMPTY APPLEEVENT. */
- kCustomEventClass, /* Event class. */
- typeAppMessage, /* Event ID. */
- &remoteLoc, /* Address of receiving app. */
- kAutoGenerateReturnID, /* This value causes the */
- /* AppleEvent manager to */
- /* assign a return ID that */
- /* is unique to the session. */
- kAnyTransactionID, /* Ignore transaction ID. */
- &theAevt /* Location of event. */
- );
-
- if (!err) /* Say what the message is. */
- AEPutParamPtr(&theAevt,keyDirectObject, typeShortInteger, (Ptr)&messageType, sizeof(short));
-
- if (!err) { /* Say what window message is for. */
- for (i = 0; i < 2; ++i) windTag[i] = (*frHndl)->connect.windowTag[i];
- AEPutParamPtr(&theAevt, keyWindowTag, typeDoubleLong, (Ptr)windTag, 2 * sizeof(long));
- }
-
- /* The stuff that applies to all messages is now done. Now specifically
- ** handle all the different message types. */
-
- if (!err) {
- switch (messageType) {
-
- case kDisconnectMssg:
- /* All the information we need is already in the AppleEvent. */
- break;
-
- case kTextMssg:
- te = (*frHndl)->d.doc.outBox;
- hText = (*te)->hText;
- hstate = LockHandleHigh(hText);
- size = (*te)->teLength;
- err = AEPutParamPtr(
- &theAevt,
- keyAppMessage,
- typeTextMessage,
- *hText,
- size
- );
- HSetState(hText, hstate);
- break;
-
- case kStylMssg:
- styl = CTEGetFullStylScrap((*frHndl)->d.doc.outBox);
- if (styl) {
- LockHandleHigh((Handle)styl);
- size = GetHandleSize((Handle)styl);
- err = AEPutParamPtr(
- &theAevt,
- keyStylMessage,
- typeStylMessage,
- (Ptr)*styl,
- size
- );
- DisposeHandle((Handle)styl);
- }
- break;
- }
- }
-
- if (!err) { /* If everything looks good... */
- err = AESend( /* SEND APPLEEVENT. */
- &theAevt, /* Our Apple Event to send. */
- &reply, /* We may have a reply. */
- kAENoReply, /* Don't wait for reply. */
- kAENormalPriority, /* App. send priority. */
- 0, /* We aren't waiting. */
- nil, /* No wait, no filter. */
- nil /* EventFilterProcPtr. */
- );
- }
-
- if (!err) {
- switch (messageType) {
- case kDisconnectMssg:
- (*frHndl)->connect.connected = false;
- (*frHndl)->connect.remoteLoc.dataHandle = nil;
- (*frHndl)->connect.remotePath[0] = 0;
- break;
- case kTextMssg:
- CTESetSelect(0, (*te)->teLength, te);
- /* Select all the text so entering the next message is more convenient. */
- break;
- }
- }
-
- AEDisposeDesc(&theAevt);
- AEDisposeDesc(&reply);
- /* Dispose of the descriptors, created or not. If not created, no harm done by calling. */
-
- SetPort(oldPort);
- return(err);
- }
-
-
-
- /*****************************************************************************/
-
-
-
- #pragma segment AppleEvents
- static pascal OSErr ReceiveMessage(AppleEvent *message, AppleEvent *reply, long refcon)
- {
- #ifndef __MWERKS__
- #pragma unused (reply, refcon)
- #endif
-
- OSErr err;
- short messageType;
- WindowPtr window;
- FileRecHndl frHndl;
- DescType actualType;
- long actualSize, windTag[2];
- AEAddressDesc remoteLoc;
- Handle mssgData;
- StScrpHandle stylData;
- TEHandle te;
- char hstate;
- long mssgSize, stylSize;
- ControlHandle ctl;
-
- err = AEGetParamPtr( /* GET THE MESSAGE TYPE. */
- message, /* The AppleEvent. */
- keyDirectObject, /* AEKeyword */
- typeShortInteger, /* Desired type. */
- &actualType, /* Type code. */
- (Ptr)&messageType, /* Pointer to area for data. */
- 2 * sizeof(long), /* Size of data area. */
- &actualSize /* Returned size of data. */
- );
-
- if (!err) {
- err = AEGetParamPtr( /* GET WINDOW MESSAGE IS FOR. */
- message, /* The AppleEvent. */
- keyWindowTag, /* AEKeyword */
- typeDoubleLong, /* Desired type. */
- &actualType, /* Type code. */
- (Ptr)windTag, /* Pointer to area for data. */
- 2 * sizeof(long), /* Size of data area. */
- &actualSize /* Returned size of data. */
- );
- }
-
- if (!err) { /* See if the requested window exists... */
- window = GetAEWindow(windTag[1], windTag[0]);
- if (window) {
- frHndl = (FileRecHndl)GetWRefCon(window);
- /* The window still exists... */
- }
- else
- err = userCanceledErr;
- /* User (or computer) canceled connection by disconnecting improperly. */
- }
-
- if (!err) { /* If everything is cool, then do the specific task... */
-
- switch(messageType) {
-
- case kDisconnectMssg:
- remoteLoc = (*frHndl)->connect.remoteLoc;
- AEDisposeDesc(&remoteLoc);
- (*frHndl)->connect.connected = false;
- (*frHndl)->connect.remoteLoc.dataHandle = nil;
- (*frHndl)->connect.remotePath[0] = 0;
- CNum2Ctl(window, 1020, &ctl);
- (*ctl)->contrlVis = false;
- BeginFrame(window);
- CNum2Ctl(window, 1010, &ctl);
- ShowStyledControl(ctl);
- CNum2Ctl(window, 1000, &ctl);
- (*ctl)->contrlVis = false;
- CNum2Ctl(window, 1002, &ctl);
- DoDraw1Control(ctl, false);
- EndFrame(window);
- break;
-
- case kTextMssg:
- if (!err) { /* Determine the size of the data... */
- err = AEGetParamPtr(
- message, /* The AppleEvent. */
- keyAppMessage, /* AEKeyword */
- typeTextMessage, /* Desired type. */
- &actualType, /* Type code. */
- nil, /* Pointer to area for data. */
- 0, /* Size of data area. */
- &mssgSize /* Returned size of data. */
- );
- }
- mssgData = nil;
- if (!err) { /* Get the data... */
- mssgData = NewHandle(mssgSize);
- if (mssgData) {
- hstate = LockHandleHigh(mssgData);
- err = AEGetParamPtr(
- message, /* The AppleEvent. */
- keyAppMessage, /* AEKeyword */
- typeTextMessage, /* Desired type. */
- &actualType, /* Type code. */
- *mssgData, /* Pointer to area for data. */
- mssgSize, /* Size of data area. */
- &actualSize /* Returned size of data. */
- );
- HSetState(mssgData, hstate);
- }
- else err = memFullErr;
- }
- if (!err) {
- BeginContent(window);
- /* Clip out all but content portion of the window. */
-
- te = (*frHndl)->d.doc.inBox;
- stylData = (*frHndl)->d.doc.textStyl;
- mssgData = CTESwapText(te, mssgData, stylData, true);
- if (stylData) {
- DisposeHandle((Handle)stylData);
- (*frHndl)->d.doc.textStyl = nil;
- }
-
- EndContent(window);
- /* Fix the window back to normal. */
- }
-
- if (mssgData)
- DisposeHandle(mssgData);
-
- if (!err)
- NotifyUser();
-
- break;
-
- case kStylMssg:
- if (!err) { /* Determine the size of the data... */
- err = AEGetParamPtr(
- message, /* The AppleEvent. */
- keyStylMessage, /* AEKeyword */
- typeStylMessage, /* Desired type. */
- &actualType, /* Type code. */
- nil, /* Pointer to area for data. */
- 0, /* Size of data area. */
- &stylSize /* Returned size of data. */
- );
- }
- stylData = nil;
- if (!err) { /* Get the data... */
- stylData = (StScrpHandle)NewHandle(stylSize);
- if (stylData) {
- hstate = LockHandleHigh((Handle)stylData);
- err = AEGetParamPtr(
- message, /* The AppleEvent. */
- keyStylMessage, /* AEKeyword */
- typeStylMessage, /* Desired type. */
- &actualType, /* Type code. */
- (Ptr)*stylData, /* Pointer to area for data. */
- stylSize, /* Size of data area. */
- &actualSize /* Returned size of data. */
- );
- HSetState((Handle)stylData, hstate);
- (*frHndl)->d.doc.textStyl = stylData;
- }
- else err = memFullErr;
- }
- break;
-
- }
- }
-
- return(err);
- }
-
-
-
-